#include "../StdInc.h"
namespace GSTrader
{
	namespace Indicator
	{
		MA::MA()
		{
			m_strIndicatorName = "MA";
			m_nLines = 0;		
			m_piLength = NULL;
			m_barType = bdtClose;
		}

		MA::~MA()
		{
			_delarr(m_piLength)
		
		}

		CIndicator* MA::CreateInstance()
		{
			return new MA;
		}

		void MA::SetOneParam(int nLength, int barType)
		{
			double dParam[3];
			dParam[0] = 1;
			dParam[1] = barType;
			dParam[2] = nLength;
	
			SetParam(dParam);
		}

		void MA::SetParam( double* pdParam)
		{
			_delarr(m_piLength)

			if (pdParam)
			{
				m_nLines = (int)pdParam[0];
				m_barType = (int)pdParam[1];
				if (m_nLines > 0)
				{
					m_piLength = new int[m_nLines];
					for (int x = 0; x < m_nLines; x++)
					{
						m_piLength[x] = (int)pdParam[x + 2];
						if (m_piLength[x] < 0)
						{
							assert(false);
							m_piLength[x] = 0;
						}
					}
				}

				size_t nSize = m_vResult.size();
				for (int x = (int)nSize; x < m_nLines; x++)
				{
					CIndicatorResult* pResult = new CIndicatorResult;
					m_vResult.push_back(pResult);
				}
			}

			RefreshData();
		}

		void MA::RefreshData()
		{
			if (m_pInput == NULL || m_pInput->m_nStartIndex < 0 || m_nLines <= 0 || m_piLength == NULL || m_pInput->m_nStartIndex < 0)
			{
				size_t nSize = m_vResult.size();
				for (int x = 0; x < m_nLines; x++)
				{
					m_vResult[x]->m_pDataSeries->m_nStartIndex = -1;
				}
				return;
			}
				
			int nCount = m_pInput->GetCount();
			size_t nSize = m_vResult.size();

			assert((int)nSize >= m_nLines);
			for (int x = 0; x < m_nLines; x++)
			{
				int nLength = m_piLength[x];
				
				int nStartIndex = m_pInput->m_nStartIndex + nLength - 1;
				m_vResult[x]->m_pDataSeries->SetSize(nCount, nStartIndex);
			}

			m_bCalc = true;
		}

		void MA::CalcMa(int nIndex, int nLineIndex)
		{
			int nLength = m_piLength[nLineIndex];
			if (m_pInput == NULL || nLength <= 0)
				return;

			int nCount = m_pInput->GetCount();
			int nStartIndex = nIndex - nLength + 1;
			if (nStartIndex < 0 || nIndex >= nCount)
				return;

			int nEndIndex = nStartIndex + nLength;

			double dSum = 0, dValue;
			for (int x = nStartIndex; x < nEndIndex; x++)
			{
				dSum += m_pInput->GetValue(x, m_barType);
			}

			dValue = dSum / nLength;
			m_vResult[nLineIndex]->SetValue(nIndex, dValue);
		}

		double MA::Calculate(int nIndex)
		{
			if (m_nLines <= 0 || m_piLength == NULL || m_pInput == NULL || m_pInput->m_nStartIndex < 0)
				return 0;

			for (int x = 0; x < m_nLines; x++)
			{
				CalcMa(nIndex, x);
			}

			return 1;
		}
	}
}